`timescale 1ns / 1ps
module test_pll(
    input resetn,
    output reg clk,
    output real vco_phase,
    output real vco_phase_io,
    input  real pfd_phase,
    input  signed [6:0] minus_1
);

parameter real icp = 200e-6;
parameter real ta_gain = 20;
parameter real r = 900;
parameter real c1 = 1.975e-8;
parameter real c2 = 1.234e-9;
parameter real Kvco = 200e4;
parameter real Fxo = 1e8;
parameter Fsamp_amp = 100;

integer file_vco;

integer i;
reg inter_clk, clk_next, clk_next_next;
// reg signed [6:0] minus_1_next;

always #1 inter_clk = !inter_clk;
always @ (posedge inter_clk) begin
    if (i == Fsamp_amp - 1) begin
        clk = !clk;
        i = 0;
    end else begin
        i = i + 1;
    end
end

initial begin
    i = 0;
    clk = 1;
    inter_clk = 1;
    file_vco=$fopen("vco_phase.csv");
end

localparam real tsamp = 1.0 / Fxo / Fsamp_amp;
real phase_vco, vc1, vtune,phase_vco_io;
real ic1, ic2, real_icp_avg;
always @ (posedge inter_clk, negedge resetn) begin
    if (!resetn) begin
        ic1 <= 0;
        ic2 <= 0;
        phase_vco <= 0;
        phase_vco_io <=0;
        real_icp_avg <= 0;
        vc1 <= 0;
        vtune <= 0;
        clk_next <= 0;
        clk_next_next <= 0;
    end else begin
        real_icp_avg = -pfd_phase * ta_gain * icp;
        ic1          =                (vtune - vc1) / r;
        ic2          = real_icp_avg - (vtune - vc1) / r;
        vc1          = vc1   + ic1 * tsamp / c1;
        vtune        = vtune + ic2 * tsamp / c2;
        clk_next <= clk;
        clk_next_next <= clk_next;
    end 
end
// always @ (posedge clk, negedge resetn) begin
//     if (!resetn) begin
//         vco_phase = 0;
//     end else begin
//         vco_phase = phase_vco;
//     end
// end

always @ (posedge clk) begin 
	$fwrite(file_vco,"%f\n",vco_phase_io);
end

parameter real frac=0.1907;
parameter real k=Fxo/1.907;

always @ (posedge inter_clk) begin 
	//vco_phase_io = vco_phase_io + (vtune * Kvco) * tsamp-0.000953655;
	
	vco_phase_io = vco_phase_io + (vtune * Kvco) * tsamp;
	vco_phase = vco_phase+(vtune * Kvco) * tsamp- ((!clk_next_next && clk_next) ? minus_1-0.1907310485 : 0);
	//vco_phase = vco_phase+(vtune * Kvco) * tsamp- ((!clk_next_next && clk_next) ? minus_1: 0);
end

//real sum,j,ave;
//parameter real frac=0.3012;
//parameter real k=1.0/Fxo;
//always @ (posedge inter_clk, negedge resetn) begin
//    if (!resetn) begin
//        sum<=0;
//    end
//    else
//        sum<=sum+(vtune * Kvco-frac*k) * tsamp;
        //sum<=sum+(vtune * Kvco) * tsamp;
//end

//assign j=j+((!clk_next_next && clk_next) ? 1 : 0);
//assign ave=(!clk_next_next && clk_next) ? sum/j : ave;
endmodule